﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace pswb.Controls
{
    public partial class ProcessSection : UserControl
    {
        #region Private Variables
        private string _sectionTitle;
        private bool isInternalDrag = false;
        private int controlNumber = 1;
        #endregion

        #region Events
        public event EventHandler onFieldSelect;
        public event EventHandler onChange; //Fired when a field is added/removed/changed
        #endregion

        #region Properties
        [CategoryAttribute("Section"), DescriptionAttribute("Title text of section")]
        public string SectionTitle
        {
            get { return _sectionTitle; }
            set
            {
                _sectionTitle = value;
                lblTitle.Text = value;
                if(onChange != null)
                onChange(new object(), new EventArgs());
            }
        }
        #endregion

        #region Private Methods
        public ProcessSection()
        {
            InitializeComponent();
        }

        private void UserControl1_Load(object sender, EventArgs e)
        {
            tablePanel.AllowDrop = true;
        }

        private void tablePanel_DragEnter(object sender, DragEventArgs e)
        {
            if (e.AllowedEffect == DragDropEffects.Copy)
                e.Effect = DragDropEffects.Copy;
            else
                e.Effect = DragDropEffects.Move;
        }

        private void tablePanel_DragDrop(object sender, DragEventArgs e)
        {
            if (e.AllowedEffect == DragDropEffects.Move)
                isInternalDrag = true;
            else
                isInternalDrag = false;

            Padding pad = new System.Windows.Forms.Padding(0);
            tablePanel.Margin = pad;
            tablePanel.Padding = pad;
            //Button lb;
            FieldTypeDisplay lb;
            
            if (e.Effect == DragDropEffects.Move)
                lb = e.Data.GetData(typeof(FieldTypeDisplay)) as FieldTypeDisplay;
            else
            {
                lb = new FieldTypeDisplay();
                lb.Text = (controlNumber++).ToString();
                lb.AutoSize = false;
                lb.Margin = pad;
                lb.Padding = pad;
                lb.Dock = DockStyle.Fill;
                lb.onMouseDown += new MouseEventHandler(lb_onMouseDown);
                lb.onSelect += new EventHandler(lb_onSelect);
                lb.onChange += new EventHandler(lb_onChange);
            }
            Point loc = this.tablePanel.PointToClient(new Point(e.X, e.Y));
            //detemine the cell location
            int ColumnIndex = -1;
            int RowIndex = -1;
            int x = 0;
            int y = 0;
            while (ColumnIndex <= this.tablePanel.ColumnCount)
            {
                if (loc.X < x)
                {
                    break;
                }
                ColumnIndex++;
                x += this.tablePanel.GetColumnWidths()[ColumnIndex];
            }
            while (RowIndex <= this.tablePanel.RowCount)
            {
                if (loc.Y < y)
                {
                    break;
                }
                RowIndex++;
                y += this.tablePanel.GetRowHeights()[RowIndex];
            }

            this.SuspendLayout();
            if (!isInternalDrag && RowIndex == this.tablePanel.RowStyles.Count - 1)
                this.tablePanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 30F));
            this.tablePanel.Controls.Add(lb, ColumnIndex, RowIndex);
            
            lb.InitializeProperties(ColumnIndex, RowIndex);
            tablePanel.RowCount = tablePanel.RowStyles.Count;
            this.Height = tablePanel.Height + lblTitle.Height;

            RemoveEmptyRows();

            if (isInternalDrag)
                AppendEmptyRow();

            tablePanel.Refresh();
            this.ResumeLayout();

            isInternalDrag = false;
            //raise the selection event
            onFieldSelect(lb, new EventArgs());
            onChange(this, new EventArgs());
        }

        void lb_onChange(object sender, EventArgs e)
        {
            onChange(this, e);
        }

        void lb_onSelect(object sender, EventArgs e)
        {
            onFieldSelect(sender, e);
        }

        void lb_onMouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                isInternalDrag = true;
                FieldTypeDisplay b = (FieldTypeDisplay)sender;
                b.DoDragDrop(b, DragDropEffects.Move);
            }
        }

        private void lblTitle_Click(object sender, EventArgs e)
        {
            onFieldSelect(this, e);
        }

        private void tablePanel_Click(object sender, EventArgs e)
        {
            onFieldSelect(this, e);
        }

        private void AppendEmptyRow()
        {
            bool hasControl = false;
            for (int col = 0; col < tablePanel.ColumnCount; col++)
            {
                if (tablePanel.GetControlFromPosition(col, tablePanel.RowCount - 1) != null)
                {
                    hasControl = true;
                    break;
                }
            }
            if (hasControl)
            {
                this.tablePanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 30F));
                tablePanel.RowCount = tablePanel.RowStyles.Count;
            }
        }

        private void RemoveEmptyRows()
        {
            if (tablePanel.RowCount == 2) return;
            for (int row = 0; row < tablePanel.RowCount - 1; row++)
            {
                bool hasControl = false;
                for (int col = 0; col < tablePanel.ColumnCount; col++)
                {
                    if (tablePanel.GetControlFromPosition(col, row) != null)
                    {
                        hasControl = true;
                        break;
                    }
                }
                if (!hasControl)
                {
                    tablePanel.RowStyles.RemoveAt(row);
                    tablePanel.RowCount = tablePanel.RowStyles.Count;
                }
            }
        }
        #endregion

        #region Public Methods
        public void AddField(Guid id, string text, int row, int col, int rowspan, int colspan)
        {
            Padding pad = new System.Windows.Forms.Padding(0);
            tablePanel.Margin = pad;
            tablePanel.Padding = pad;
            //Button lb;
            FieldTypeDisplay lb;

            lb = new FieldTypeDisplay();
            lb.isNew = false; //prevent auto initialization
            lb.Text = text;
            lb.AutoSize = false;
            lb.Margin = pad;
            lb.Padding = pad;
            lb.Dock = DockStyle.Fill;
            lb.onMouseDown += new MouseEventHandler(lb_onMouseDown);
            lb.onSelect += new EventHandler(lb_onSelect);
            lb.onChange += new EventHandler(lb_onChange);

            if (rowspan > 0)
                this.tablePanel.SetRowSpan(lb, rowspan);
            else
                rowspan = 1;
            if (colspan > 0)
                this.tablePanel.SetColumnSpan(lb, colspan);
            else
                colspan = 1;

            this.tablePanel.Controls.Add(lb, col, row);

            //set properties of the field
            lb.setID(id);
            lb.Row = row;
            lb.Column = col;
            lb.RowSpan = rowspan;
            lb.ColumnSpan = colspan;
            lb.Label = text;

            lb.InitializeProperties(col, row);
            tablePanel.RowCount = tablePanel.RowStyles.Count;
            this.Height = tablePanel.Height + lblTitle.Height;

            //RemoveEmptyRows();
            AppendEmptyRow();

            tablePanel.Refresh();
        }
        #endregion
    }
}
